/**
 * 
 */
package neptune.manager.storage;

import neptune.manager.ExperimentException;
import neptune.manager.model.experiment.Experiment;

/**
 * L'interfaccia deve essere implementata dalla classe che realizza il
 * repository per gli esperimenti. <br>
 * <br>
 * Il repository realizza le azioni elementari di modifica dei dati. La gestione
 * della logica legata a queste modifiche e' da implementare all'interno della
 * classe ExperimentsManager.
 * 
 * @author Roberto Bifulco [info@robertobifulco.it, robertobifulco.it]
 * 
 */
public interface ExperimentsRepository {

	/**
	 * Restituisce tutti gli esperimenti presenti nel repository. Se non ci sono
	 * esperimenti restituisce null.
	 * 
	 * @return
	 */
	public String[] getExperiments() throws ExperimentRepositoryException;

	/**
	 * Restituisce solo gli esperimenti attivi presenti nel repository. Se non
	 * ce ne sono restituisce null.
	 * 
	 * @return
	 */
	public String[] getActiveExperiments() throws ExperimentRepositoryException;

	/**
	 * Restituisce un esperimento presente nel repository, identificato dal suo
	 * nome. Se non c'e' tale esperimento, restituisce null.
	 * 
	 * @param name
	 * @return
	 */
	public Experiment getExperimentByName(String name)
			throws ExperimentRepositoryException;

	/**
	 * Aggiunge un esperimento al repository
	 * 
	 * @param experiment
	 * @exception ExperimentException
	 *                tipicamente lanciata se l'identificativo dell'esperimento
	 *                non e' univoco
	 */
	public void addExperimentToRepository(Experiment experiment)
			throws ExperimentException, ExperimentRepositoryException;

	/**
	 * Elimina un esperimento dal repository
	 * 
	 * @param experiment
	 */
	public void deleteExperiment(Experiment experiment)
			throws ExperimentRepositoryException;

	/**
	 * Aggiorna lo stato di un esperimento nel repository. Questo metodo e'
	 * usato, ad esempio, per aggiungere nuovi utenti all'esperimento.
	 * 
	 * @param experiment
	 * @throws ExperimentRepositoryException
	 */
	public void updateExperiment(Experiment experiment)
			throws ExperimentRepositoryException;

	/**
	 * Crea un esperimento nel repository, fornendo le informazioni essenziali
	 * 
	 * @param expName
	 * @param expAdmin
	 * @throws ExperimentRepositoryException
	 */
	public void createExperiment(String expName, String expAdmin,
			long creationTimestamp) throws ExperimentRepositoryException;

	/**
	 * Elimina l'esperimento con il dato nome identificativo
	 * 
	 * @param expName
	 * @throws ExperimentException
	 */
	public boolean deleteExperiment(String expName)
			throws ExperimentRepositoryException;

	/**
	 * Aggiorna lo stato di un esperimento
	 * 
	 * @param expName
	 * @param expState
	 * @throws ExperimentRepositoryException
	 */
	public void setExperimentState(String expName, String expState)
			throws ExperimentRepositoryException;

	/**
	 * Restituisce lo stato dell'esperimento il cui identificativo e' passato
	 * come argomento.
	 * 
	 * @param expName
	 * @return
	 * @throws ExperimentRepositoryException
	 */
	public String getExperimentState(String expName)
			throws ExperimentRepositoryException;

	/**
	 * Imposta il timestamp di avvio dell'esperimento (allocazione e
	 * configurazione sul cluster)
	 * 
	 * @param timestamp
	 * @throws ExperimentRepositoryException
	 */
	public void setExperimentStartTime(String expId,long timestamp)
			throws ExperimentRepositoryException;

	/**
	 * Ottiene il timestamp di avvio dell'esperimento (allocazione e
	 * configurazione sul cluster)
	 * 
	 * @param timestamp
	 * @throws ExperimentRepositoryException
	 */
	public long getExperimentStartTime(String expId) throws ExperimentRepositoryException;

	/**
	 * Imposta il timestamp di deallocazione dell'esperimento.
	 * 
	 * @param timestamp
	 * @throws ExperimentRepositoryException
	 */
	public void setExperimentStopTime(String expId,long timestamp)
			throws ExperimentRepositoryException;

	/**
	 * Ottiene il timestamp di deallocazione dell'esperimento.
	 * 
	 * @param timestamp
	 * @throws ExperimentRepositoryException
	 */
	public long getExperimentStopTime(String expId) throws ExperimentRepositoryException;

	/**
	 * Ottiene l'insieme di coppie nome utente - ruolo per il dato esperimento.
	 * 
	 * @param exp
	 * @return
	 * @throws ExperimentRepositoryException
	 */
	public String[][] getExperimentUsers(String exp)
			throws ExperimentRepositoryException;

	/**
	 * Aggiunge un utente usr all'esperimento exp con ruolo role
	 * 
	 * @param exp
	 * @param usr
	 * @param role
	 * @throws ExperimentRepositoryException
	 */
	public void addExperimentUser(String exp, String usr, String role)
			throws ExperimentRepositoryException;

	/**
	 * Elimina un utente usr all'esperimento exp
	 * 
	 * @param exp
	 * @param usr
	 * @throws ExperimentRepositoryException
	 */
	public void deleteExperimentUser(String exp, String usr)
			throws ExperimentRepositoryException;

	/**
	 * Ottiene il numero di esperimenti in cui e' coinvolto un utente. Se
	 * l'utente e' l'amministratore di sistema, gli esperimenti considerati sono
	 * tutti quelli definiti sul sistema stesso.
	 * 
	 * @param username
	 * @param isSystemAdmin
	 * @return experiments number
	 * @throws ExperimentRepositoryException
	 */
	public int getExperimentNumberForUser(String username, boolean isSystemAdmin)
			throws ExperimentRepositoryException;

	/**
	 * Ottiene un array bidimensionale rappresentante i dati della tabella che
	 * contiene gli esperimenti. I parametri passati servono per organizzare
	 * l'ordinamento dei dati e per ottenere un sottoinsieme degli stessi.
	 * L'array restituito ha per ogni riga una riga della tabella, per ogni
	 * colonna la corrispondente colonna che deve essere adoperata nella
	 * visualizzazione.
	 * 
	 * Gli esperimenti recuperati fanno riferimento soltanto all'utente il cuui
	 * username e' passato come argomento.
	 * 
	 * @param begin
	 * @param end
	 * @param sortId
	 * @param ascending
	 * @return
	 * @throws ExperimentRepositoryException
	 */
	public String[][] getExperimentTable(int begin, int end, int sortId,
			boolean ascending, String username, boolean isAdmin)
			throws ExperimentRepositoryException;

	/**
	 * Restituisce l'identificativo dell'amministratore dell'esperimento passato
	 * come argomento
	 * 
	 * @param expName
	 * @return
	 * @throws ExperimentRepositoryException
	 */
	public String getExperimentAdmin(String expName)
			throws ExperimentRepositoryException;
}
